package com.higgins.eventtracking.server;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import com.higgins.eventtracking.client.EventTrackingService;
import com.higgins.eventtracking.client.SecurityAccessDeniedException;
import com.higgins.eventtracking.client.dto.BodyStatsDTO;
import com.higgins.eventtracking.client.dto.ChartDataDTO;
import com.higgins.eventtracking.client.dto.FinanceStatsDTO;
import com.higgins.eventtracking.client.dto.GoalDTO;
import com.higgins.eventtracking.client.dto.HealthAlertDTO;
import com.higgins.eventtracking.client.dto.HealthEventDTO;
import com.higgins.eventtracking.client.dto.HealthStatsDTO;
import com.higgins.eventtracking.client.dto.RuleDTO;
import com.higgins.eventtracking.client.dto.SupportDTO;
import com.higgins.eventtracking.client.dto.TimeTableTaskDTO;
import com.higgins.eventtracking.client.dto.TrackingEventDTO;
import com.higgins.eventtracking.client.dto.TransactionDTO;
import com.higgins.eventtracking.client.dto.WeightEventDTO;
import com.higgins.eventtracking.server.dataModel.BodyStats;
import com.higgins.eventtracking.server.dataModel.HealthEvent;
import com.higgins.eventtracking.server.dataModel.TrackingEvent;
import com.higgins.eventtracking.server.dataModel.WeightEvent;
import com.higgins.eventtracking.shared.FieldVerifier;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class EventTrackingServiceImpl extends RemoteServiceServlet implements
		EventTrackingService {
	
	private void checkAuthority() throws SecurityAccessDeniedException	{
		UserService userService = UserServiceFactory.getUserService();
		User currentUser = userService.getCurrentUser();
		if ((currentUser!=null) && (currentUser.getEmail().equals("test@example.com") || 
				currentUser.getEmail().toLowerCase().equals("pshiggins@gmail.com")))
			System.out.println("Grant Access");
		else
			throw new SecurityAccessDeniedException();
	}
	
	public String insertTrackingEvent(TrackingEventDTO trackingEventDTO) throws IllegalArgumentException {
		String serverInfo = getServletContext().getServerInfo();
		String userAgent = getThreadLocalRequest().getHeader("User-Agent");

		// Escape data from the client to avoid cross-site script vulnerabilities.
		userAgent = escapeHtml(userAgent);
		
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		boolean success = dataStore.insertTrackingEvent(new TrackingEvent(trackingEventDTO));
		
		String response = "Insert was " + (success?"":"un") + "successful for "+ trackingEventDTO.getEventType() + " event.\n";

//		return "Hello, " + trackingEventDTO.getEventType() + "!<br><br>I am running " + serverInfo
//				+ ".<br><br>It looks like you are using:<br>" + userAgent;
		dataStore.closePersistenceManager();
		return response;
	}

	@Override
	public Boolean insertFrameOfMind(String frameOfMind)
			throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		boolean success = dataStore.insertFrameOfMind(frameOfMind);
		
		dataStore.closePersistenceManager();
		return success;
	}
	
	@Override
	public Boolean frameOfMindSetToday() throws IllegalArgumentException 	{
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		boolean setToday = dataStore.frameOfMindSetToday();
		
		dataStore.closePersistenceManager();
		return setToday;
	}
	@Override
	public Boolean healthEventToday(String healthEventType) throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		boolean setToday = dataStore.healthEventToday(healthEventType);
		
		dataStore.closePersistenceManager();
		return setToday;
	}
	
	public TrackingEventDTO retrieveTrackingEvent(String eventType) throws IllegalArgumentException	{
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		TrackingEvent event = dataStore.retrieveBestTrackingEvent(eventType);
		dataStore.closePersistenceManager();
		if (event!=null)	{
			return event.getDTO();
		}		
		return null;
	}
	
	public String insertTransaction(TransactionDTO dto) throws IllegalArgumentException	{
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		boolean success = dataStore.insertTransaction(dto);
		
		String response = "Insert was " + (success?"":"un") + "successful for "+ dto.getDescription() + " event.\n";

		dataStore.closePersistenceManager();
		return response;
	}
/*
	public FinanceStatsDTO retrieveFinanceStats() throws IllegalArgumentException	{
		FinanceStatsDTO dto = new FinanceStatsDTO();
		try	{
			checkAuthority();
			Date now = new Date();
			DataStoreService dataStore = new DataStoreService();
			dataStore.openPersistenceManager();
			
			
			Double totalSpentThisWeek = dataStore.getTotalSpentThisWeek();
			Double averageWeeklySpendThisMonth = dataStore.getAverageWeeklySpentThisMonth();
			Integer weekNumber = dataStore.getWeekNumber(now);
			Double expectedSavingThisMonth = 1700.0 - (averageWeeklySpendThisMonth * dataStore.getNumberOfWeeksInMonth(now));
			Double spentThisMonth = (averageWeeklySpendThisMonth*(weekNumber-1)) + totalSpentThisWeek;
			Double totalRemainingThisMonth = 1700.0 - ((averageWeeklySpendThisMonth*(weekNumber-1)) + totalSpentThisWeek);
			
			dto.setTotalSpentThisWeek(roundTwoDecimals(totalSpentThisWeek));
			dto.setAverageWeeklySpentThisMonth(roundTwoDecimals(averageWeeklySpendThisMonth));
			dto.setWeekNumber(weekNumber);
			dto.setExpectedSavingThisMonth(roundTwoDecimals(expectedSavingThisMonth));
			dto.setSpentThisMonth(roundTwoDecimals(spentThisMonth));
			dto.setTotalRemainingThisMonth(roundTwoDecimals(totalRemainingThisMonth));
			
			dataStore.closePersistenceManager();
		} catch (Exception e)	{	}
		return dto;
	}		*/

	public String insertHealthEvent(HealthEventDTO dto) throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();

		boolean success = dataStore.insertHealthEvent(new HealthEvent(dto));
		
		String response = "Insert was " + (success?"":"un") + "successful for "+ dto.getHealthEventType() + " event.\n";

		dataStore.closePersistenceManager();
		return response;
	}
	
	public String insertBodyEvent(BodyStatsDTO dto) throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();

		boolean success = dataStore.insertBodyEvent(new BodyStats(dto));
		
		String response = "Insert was " + (success?"":"un") + "successful \n";

		dataStore.closePersistenceManager();
		return response;
	}
	
	public HealthStatsDTO retrieveHealthStats()	throws IllegalArgumentException	{
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		
		HealthStatsDTO dto = new HealthStatsDTO();
		dto.setIllOrInjured(dataStore.retrieveIllOrInjured());
		dto.setHealthPoints(dataStore.retrieveTodaysHealtPoints());
		
		dataStore.closePersistenceManager();
		return dto;
	}
	
	public Calendar setDateToMidday(Date date)	{
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.HOUR_OF_DAY, 12);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		return cal;
	}
	
	public List<HealthStatsDTO> retrieveHealthStats(Date start, Date end)	throws IllegalArgumentException	{
		List<HealthStatsDTO> dtoList = new ArrayList<HealthStatsDTO>();
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		Calendar calCurrent = setDateToMidday(start);
		
		Calendar calEnd = setDateToMidday(end);
		calEnd.add(Calendar.MINUTE, +1);
		
		while (calCurrent.before(calEnd))	{
			HealthStatsDTO dto = new HealthStatsDTO();
			dto.setDate(calCurrent.getTime());
			dto.setHealthPoints(dataStore.retrieveHealthPoints(calCurrent));
			dtoList.add(dto);
			calCurrent.add(Calendar.DAY_OF_MONTH, +1);
			calCurrent.set(Calendar.HOUR_OF_DAY, 12);
			calCurrent.set(Calendar.MINUTE, 0);
			calCurrent.set(Calendar.SECOND, 0);
		}
		
		
		dataStore.closePersistenceManager();
		return dtoList;
	}
	
	
	double roundTwoDecimals(double d) {
        DecimalFormat twoDForm = new DecimalFormat("#.##");
        return Double.valueOf(twoDForm.format(d));
	}

	/**
	 * Escape an html string. Escaping data received from the client helps to
	 * prevent cross-site script vulnerabilities.
	 * 
	 * @param html the html string to escape
	 * @return the escaped string
	 */
	private String escapeHtml(String html) {
		if (html == null) {
			return null;
		}
		return html.replaceAll("&", "&amp;").replaceAll("<", "&lt;")
				.replaceAll(">", "&gt;");
	}

	/*
	@Override
	public ChartDataDTO retrieveFinanceChartData(Boolean weeklyChart)
			throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		List<Double> list = dataStore.getFinanceChartData(weeklyChart, 10);
		
		dataStore.closePersistenceManager();
		ChartDataDTO chartData = new ChartDataDTO();
		chartData.setData(list);
		return chartData;
	}	*/
	@Override
	public List<Double> retrieveExerciseChartData(String exercise)
			throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		List<Double> list = dataStore.getExerciseChartData(exercise, 5);
		
		dataStore.closePersistenceManager();
		return list;
	}

    @Override
    public List<WeightEventDTO> retrieveWeightEventChartDataDTO(String type)
            throws IllegalArgumentException {
        DataStoreService dataStore = new DataStoreService();
        dataStore.openPersistenceManager();
        
        List<WeightEventDTO> list = dataStore.getWeightEventChartDataDTO(type, 26);
        
        dataStore.closePersistenceManager();
        return list;
    }
	
	
	@Override
	public List<TrackingEventDTO> retrieveExerciseChartDataDTO(String exercise)
			throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		List<TrackingEventDTO> list = dataStore.getExerciseChartDataDTO(exercise, 26);
		
		dataStore.closePersistenceManager();
		return list;
	}
	
	@Override
	public List<Double> retrieveWeightChartData(String exercise,
			Boolean monthlyOrWeekly) throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		List<Double> list = dataStore.getWeightChartData(exercise, monthlyOrWeekly, 5);
		
		dataStore.closePersistenceManager();
		return list;
	}

	@Override
	public Integer retrieveDaysSinceExercise() throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		
		Integer daysSinceExercise = dataStore.retrieveDaysSinceExercise();
		
		dataStore.closePersistenceManager();
		return daysSinceExercise;
	}

	@Override
	public Integer retrieveDaysSinceLowFrameOfMind() throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		
		Integer daysSinceSleep = dataStore.retrieveDaysSinceLowFrameOfMind();
		
		dataStore.closePersistenceManager();
		return daysSinceSleep;
	}
	
	@Override
	public Integer retrieveDaysSinceLowWellBeing() throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		
		Integer daysSinceSleep = dataStore.retrieveDaysSinceLowWellBeing();
		
		dataStore.closePersistenceManager();
		return daysSinceSleep;
	}

    @Override
    public Integer getWellBeing() throws IllegalArgumentException {
        DataStoreService dataStore = new DataStoreService();
        dataStore.openPersistenceManager();
        
        
        Integer wellBeing = dataStore.getWellBeing();
        
        dataStore.closePersistenceManager();
        return wellBeing;
    }
	
	
	@Override
	public Integer retrieveDaysSinceLowEnergy() throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		
		Integer daysSinceSleep = dataStore.retrieveDaysSinceLowEnergy();
		
		dataStore.closePersistenceManager();
		return daysSinceSleep;
	}
	
	@Override
	public Integer retrieveDaysSinceSleep() throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		
		Integer daysSinceSleep = dataStore.retrieveDaysSinceSleep();
		
		dataStore.closePersistenceManager();
		return daysSinceSleep;
	}

	@Override
	public Integer retrieveDaysSinceDump() throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		Integer daysSinceDump = dataStore.retrieveDaysSinceDump();
		
		dataStore.closePersistenceManager();
		return daysSinceDump;
	}
	
	@Override
	public Integer retrieveDaysSinceStretch() throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		Integer daysSinceDump = dataStore.retrieveDaysSinceStretch();
		
		dataStore.closePersistenceManager();
		return daysSinceDump;
	}
	@Override
	public Integer retrieveHoursSinceBrushTeeth() throws IllegalArgumentException	{
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		Integer daysSinceBrushTeeth = dataStore.retrieveHoursSinceBrushTeeth();
		
		dataStore.closePersistenceManager();
		return daysSinceBrushTeeth;
	}

	@Override
	public Integer retrieveHoursSinceWater() throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		Integer hoursSinceWater = dataStore.retrieveHoursSinceWater();
		
		dataStore.closePersistenceManager();
		return hoursSinceWater;
	}

	@Override
	public Integer retrieveDaysSinceSalad() throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		Integer daysSinceSalad = dataStore.retrieveDaysSinceSalad();
		
		dataStore.closePersistenceManager();
		return daysSinceSalad;
	}

	@Override
	public Integer retrieveDaysSinceVeg() throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		Integer daysSinceSalad = dataStore.retrieveDaysSinceVeg();
		
		dataStore.closePersistenceManager();
		return daysSinceSalad;
	}

	@Override
	public Integer retrieveDaysSinceFruit() throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		Integer daysSinceSalad = dataStore.retrieveDaysSinceFruit();
		
		dataStore.closePersistenceManager();
		return daysSinceSalad;
	}

	@Override
	public Integer retrieveDaysSinceRoughage() throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		Integer daysSinceSalad = dataStore.retrieveDaysSinceRoughage();
		
		dataStore.closePersistenceManager();
		return daysSinceSalad;
	}

	@Override
	public Integer retrieveHoursSinceFood() throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		Integer hoursSinceFood = dataStore.retrieveHoursSinceFood();
		
		dataStore.closePersistenceManager();
		return hoursSinceFood;
	}

	@Override
	public String retrieveFirstEaten() throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		String firstEaten = dataStore.retrieveFirstEaten();
		
		dataStore.closePersistenceManager();
		return firstEaten;
	}

	@Override
	public Integer retrieveDaysSinceBloated() throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		Integer results = dataStore.retrieveDaysSinceBloated();
		
		dataStore.closePersistenceManager();
		return results;
	}

	@Override
	public Integer retrieveDaysSinceBisacodyl() throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		Integer results = dataStore.retrieveDaysSinceBisacodyl();
		
		dataStore.closePersistenceManager();
		return results;
	}

	@Override
	public Integer retrieveNumberOfBrushesToday()
			throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		Integer results = dataStore.retrieveNumberOfBrushesToday();
		
		dataStore.closePersistenceManager();
		return results;
	}

	@Override
	public List<String> retrieveAchievements() throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		List<String> results = dataStore.retrieveAchievements();
		
		dataStore.closePersistenceManager();
		return results;
	}

	@Override
	public List<String> retrieveAchievements(String frameOfMind, Integer weekNumber)
			throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		List<String> results = dataStore.retrieveAchievements(frameOfMind, weekNumber);
		
		dataStore.closePersistenceManager();
		return results;
	}
    
	@Override
	public List<String> retrieveAchievements(Date startDate, Date endDate, String intensity, String frameOfMind) throws IllegalArgumentException   {
        DataStoreService dataStore = new DataStoreService();
        dataStore.openPersistenceManager();
        
        List<String> results = dataStore.retrieveAchievements(startDate, endDate, intensity, frameOfMind);
        
        dataStore.closePersistenceManager();
        return results;
	}

	@Override
	public Integer retrieveDaysSinceFrameOfMind(String frameOfMind) throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		
		
		Integer daysSinceSleep = dataStore.retrieveDaysSinceFrameOfMind(frameOfMind);
		
		dataStore.closePersistenceManager();
		return daysSinceSleep;
	}

	@Override
	public List<HealthAlertDTO> retrieveHealthAlerts()
			throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		List<HealthAlertDTO> healthAlerts = dataStore.retrieveHealthAlerts();
		dataStore.closePersistenceManager();
		return healthAlerts;
	}

	@Override
	public List<HealthAlertDTO> retrieveHealthAlerts(String tabTitle)
			throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		List<HealthAlertDTO> healthAlerts = dataStore.retrieveHealthAlerts(tabTitle);
		dataStore.closePersistenceManager();
		return healthAlerts;
	}

	@Override
	public String updateHealthAlert(HealthAlertDTO dto)
			throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		String id = dataStore.updateHealthAlert(dto);
		dataStore.closePersistenceManager();
		return id;
	}

	@Override
	public Boolean weightEventToday(String weightEventType)
			throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		boolean setToday = dataStore.weightEventToday(weightEventType);
		
		dataStore.closePersistenceManager();
		return setToday;
	}

	@Override
	public String insertWeightEvent(WeightEventDTO weightEvent)
			throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();

		boolean success = dataStore.insertWeightEvent(new WeightEvent(weightEvent));
		
		String response = "Insert was " + (success?"":"un") + "successful for "+ weightEvent.getWeightEventType() + " event.\n";

		dataStore.closePersistenceManager();
		return response;
	}

	@Override
	public List<TimeTableTaskDTO> retrieveTimeTableTasks(Date now)
			throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		List<TimeTableTaskDTO> timetabletasks = dataStore.retrieveTimeTableTasks(now);
		dataStore.closePersistenceManager();
		return timetabletasks;
	}

	@Override
	public List<TimeTableTaskDTO> retrieveTimeTableTasks(Boolean yearly, Boolean monthly, Boolean weekly, Boolean daily, Boolean holidays, Date now)
			throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		List<TimeTableTaskDTO> timetabletasks = dataStore.retrieveTimeTableTasks(yearly, monthly, weekly, daily, holidays, now);
		dataStore.closePersistenceManager();
		return timetabletasks;
	}

	@Override
	public List<TimeTableTaskDTO> retrieveTimeTableFuel(Boolean yearly,
			Boolean monthly, Boolean weekly, Boolean daily, Boolean holidays,
			Date now) throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		List<TimeTableTaskDTO> timetabletasks = dataStore.retrieveTimeTableFuel(yearly, monthly, weekly, daily, holidays, now);
		dataStore.closePersistenceManager();
		return timetabletasks;
	}

	@Override
	public String updateTimeTableTask(TimeTableTaskDTO dto)
			throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		String id = dataStore.updateTimeTableTask(dto);
		dataStore.closePersistenceManager();
		return id;
	}

	@Override
	public List<GoalDTO> retrieveGoals(String frameOfMind)
			throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		List<GoalDTO> goals = dataStore.retrieveGoals(frameOfMind);
		dataStore.closePersistenceManager();
		return goals;
	}

	@Override
	public String updateGoal(GoalDTO goal) throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		String id = dataStore.updateGoal(goal);
		dataStore.closePersistenceManager();
		return id;
	}

	@Override
	public List<HealthEventDTO> retrieveHealthEvents(String event)
			throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		List<HealthEventDTO> dtos = dataStore.retrieveHealthEvents(event);
		dataStore.closePersistenceManager();
		return dtos;
	}
	@Override
	public List<HealthEventDTO> retrieveHealthEvents(String event, String eventTwo)
			throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		List<HealthEventDTO> dtos = dataStore.retrieveHealthEvents(event, eventTwo);
		dataStore.closePersistenceManager();
		return dtos;
	}

	@Override
	public Long deleteGoal(Long id) throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		Long returnId = dataStore.deleteGoal(id);
		dataStore.closePersistenceManager();
		return returnId;
	}

	@Override
	public String completeGoal(GoalDTO dto) throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		String returnString = dataStore.completeGoal(dto);
		dataStore.closePersistenceManager();
		return returnString;
	}

	@Override
	public Integer getWeekNumber() throws IllegalArgumentException {
		Calendar cal = Calendar.getInstance();
		return cal.get(Calendar.WEEK_OF_YEAR);
	}

	@Override
	public List<SupportDTO> retrieveSupport() throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		List<SupportDTO> supportContacts = dataStore.retrieveSupport();
		dataStore.closePersistenceManager();
		return supportContacts;
	}

	@Override
	public String updateSupport(SupportDTO support)
			throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		String id = dataStore.updateSupport(support);
		dataStore.closePersistenceManager();
		return id;
	}

	@Override
	public Long deleteSupport(Long id) throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		Long returnId = dataStore.deleteSupport(id);
		dataStore.closePersistenceManager();
		return returnId;
	}

	@Override
	public Integer getDayOfYearNumber(Date date)
			throws IllegalArgumentException {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.DAY_OF_YEAR);
	}

	@Override
	public HealthAlertDTO retrievePeriodSinceAlert(HealthAlertDTO dto)
			throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		HealthAlertDTO dtoReturned = dataStore.retrievePeriodSinceAlert(dto);
		dataStore.closePersistenceManager();
		return dtoReturned;
	}

	@Override
	public List<RuleDTO> retrieveRules(String parentDynamicType, String frameOfMind)
			throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		List<RuleDTO> rules = dataStore.retrieveRules(parentDynamicType, frameOfMind);
		dataStore.closePersistenceManager();
		return rules;
	}

   @Override
    public List<RuleDTO> retrieveRules(String parentDynamicType, String frameOfMind, Date startDate, Date endDate)
            throws IllegalArgumentException {
        DataStoreService dataStore = new DataStoreService();
        dataStore.openPersistenceManager();
        List<RuleDTO> rules = dataStore.retrieveRules(parentDynamicType, frameOfMind, startDate, endDate);
        dataStore.closePersistenceManager();
        return rules;
    }
	
	@Override
	public String updateRule(RuleDTO rules) throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		String id = dataStore.updateRule(rules);
		dataStore.closePersistenceManager();
		return id;
	}

	@Override
	public Long deleteRule(Long id) throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		Long returnId = dataStore.deleteRule(id);
		dataStore.closePersistenceManager();
		return returnId;
	}

	@Override
	public String retrieveRecommendedFrameOfMind()
			throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		try	{
			dataStore.openPersistenceManager();
			return retrieveRecommendedFrameOfMind(dataStore);
		} finally	{
			dataStore.closePersistenceManager();
		}
	}
	
	public String retrieveRecommendedFrameOfMind(DataStoreService dataStore)	{
		String[] higherEnergyOrderedFrameOfMinds = {"Software Development"};
		String[] mediumEnergyOrderedFramesOfMinds = {"House Keeping",  
							"Financial Services Law", "Economics", 
							"Banking Law", "I.T. Law",
							"Build For The Future"};
		String[] lowEnergyOrderedFrameOfMinds = {"Fiction", "Relax"};
		HealthEvent healthEvent = dataStore.retrieveCurrentHealthEvent("Energy");
		int energy = healthEvent.getHealthEventIntensityScale();
		if (energy > 7)	{
			return "Law Career";
		} else if (energy > 6)	{
			return "Software";
		} else if (energy > 5)	{		// higher energy
			return checkForNextSetOfGoals(higherEnergyOrderedFrameOfMinds, dataStore);
		} else if (energy > 4)		{
			return checkForNextSetOfGoals(mediumEnergyOrderedFramesOfMinds, dataStore);
		} else {
			return checkForNextSetOfGoals(lowEnergyOrderedFrameOfMinds, dataStore);
		}
	}
	
	private String checkForNextSetOfGoals(String[] framesOfMinds, DataStoreService dataStore)	{
		for (String frameOfMind:framesOfMinds)	{
			if (dataStore.countGoals(frameOfMind) > 0)	{
				return frameOfMind;
			}
		}
		return null;
	}

	@Override
	public Double retrieveMaxWeightThisWeek(String exercise)
			throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		try	{
			dataStore.openPersistenceManager();
			return retrieveMaxWeightThisWeek(dataStore, exercise);
		} finally	{
			dataStore.closePersistenceManager();
		}
	}

	public Double retrieveMaxWeightThisWeek(DataStoreService dataStore, String exercise)	{
		return dataStore.retrieveMaxWeightThisWeek(exercise);
	}
	
	@Override
	public Double retrieveMaxDistanceThisWeek(String exercise)
			throws IllegalArgumentException {
		DataStoreService dataStore = new DataStoreService();
		try	{
			dataStore.openPersistenceManager();
			return retrieveMaxDistanceThisWeek(dataStore, exercise);
		} finally	{
			dataStore.closePersistenceManager();
		}
	}

	public Double retrieveMaxDistanceThisWeek(DataStoreService dataStore, String exercise)	{
		return dataStore.retrieveMaxDistanceThisWeek(exercise);
	}	
}
